package com.qwiki.text;

import java.util.Collections;
import java.util.List;

/**
 * @author xgu
 * 
 * @since Jun 11, 2012
 */
public class TagXNode extends Node
{
  private static String startTag = "<";
  private static String endTag = ">";
  private static String slash = "/";

  private final String key;
  private final boolean skip;
  private String enclosed;

  /**
   * getText() returns enclosed text if any
   * 
   * @param key
   */
  public TagXNode(String key)
  {
    this.key = key;
    skip = false;
  }

  /**
   * @param key
   * @param skip
   *          true if to discard the enclosed text
   */
  public TagXNode(String key, boolean skip)
  {
    this.key = key;
    this.skip = skip;
  }

  @Override
  public String getText()
  {
    return skip ? " " : enclosed;
  }

  @Override
  public List<Node> getChildren()
  {
    return Collections.EMPTY_LIST;
  }

  @Override
  public boolean parse(char[] buffer, int start)
  {
    this.start = start;
    this.buffer = buffer;
    int i = start;
    if (match(buffer, start, startTag) && match(buffer, start + startTag.length(), key))
    {
      // matched beginning
      int close = find(buffer, endTag, start + 1 + key.length());
      if (close < 0)
        return false;
      if (buffer[close - 1] == slash.charAt(0))
      {
        // end tag of form <xxx />
        this.end = close + endTag.length();
        this.parsed = true;
        enclosed = "";
        return true;
      }
      // tag of form <xxx > ... </xxx>

      i = close + endTag.length();
      int closing = i;
      while (i < buffer.length)
      {
        // parse end of TagNode
        if (match(buffer, i, startTag) && match(buffer, i + startTag.length(), slash) && match(buffer, i + startTag.length() + 1, key)
            && match(buffer, i + startTag.length() + 1 + key.length(), endTag))
        {
          // match end
          end = i + startTag.length() + 1 + key.length() + endTag.length();
          enclosed = new String(buffer, closing, i - closing);
          parsed = true;
          return true;
        }
        i++;
      }
    }
    return false;
  }
}
